#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */


#ifndef SDK_MATHS_H
#define SDK_MATHS_H

#define HASHTYPE_1    0
#define HASHTYPE_256  1
#define COMMAND_PCIKEY_SM2CRYPT            0xB111

typedef enum
{
    SDK_DES = 0x01,                              //DES
    SDK_3DES = 0x02                             //3DES
} SDK_ENCRYPT_MODE;

typedef enum
{
    SDK_DECRYPT = 0,
    SDK_ENCRYPT = 1
} SDK_ENC_DES_MODE;


#define SDK_MAX_RSA_MODULUS_LEN  256ul
#define SDK_MAX_RSA_PRIME_LEN   128ul

typedef struct
{
    u8 PK[512];
    u32 PKLen;
    s8 subject[128];
    s8 issuer[128];
    s8 serial[32];
} SDK_CERT_INFO;


extern s32 sdkMD5(u8 *pheDest, const u8 *pheSrc, u32 siLen, bool switchToAsc);

extern s32 sdkSHA1(u8 *pheSrc, u32 siLen, u8 *pheDest);

extern s32 sdkSHA256(u8 *pheSrc, u32 siLen, u8 *pheDest);

extern s32 sdkRSAPublicEncrypt(u8 *pheDest, u32 *psiDestLen, u8 *pheSrc, u32 siSrcLen, u8 *pk, u32 pkLen);

extern s32 sdkRSAPrivateEncrypt(u8 *pheDest, u32 *psiDestLen, u8 *pucSrc, u32 siSrcLen, u8 *sk, u32 skLen);

extern s32 sdkRSARecovery(u8 *m, u32 mLen, u8 *e, u32 eLen, u8 *input, u8 *output);

extern s32 sdkRSAPublicDecrypt(u8 *pucDest, u32 *psiDestLen, u8 *pheSrc, u32 siSrcLen, u8 *pk, u32 pkLen);

extern s32 sdkRSAPrivateDecrypt(u8 *pheDest, u32 *psiDestLen, u8 *pucSrc, u32 siSrcLen, u8 *sk, u32 skLen);

extern s32 sdkRSAPrivateSign(u8 digst_alg, const u8 *hash, u8 *sig, u8 *sk, u32 skLen);

extern s32 sdkRSAPublicSign(u8 digst_alg, const u8 *hash, u8 *sig, u8 *pk, u32 pkLen);

extern s32 sdkRSAPrivateVerify(u8 digst_alg, const u8 *hash, u8 *sig, u8 *sk, u32 skLen);

extern s32 sdkRSAPublicVerify(u8 digst_alg, const u8 *hash, u8 *sig, u8 *pk, u32 pkLen);

extern s32 sdkRSAParsePKByCert(const u8 *cert, u32 certLen, SDK_CERT_INFO *certInfo);

extern s32 sdkRsaVerifyCertChain(u8 **certs, u32 certsNum);

extern s8 *sdkBase64Encode(const u8 *binData, s8 *base64, u32 binLen);

extern u32 sdkBase64Decode(const s8 *base64, u8 *binData);

extern s32 sdkAscToBcd(u8 *pbcDest, const s8 *pasSrc, u32 siSrclen);

extern bool sdkIsAscii(const u8 *pasSrc);

extern s32 sdkU8ToBcd(u8 *pbcDest, u8 const ucSrc, u32 siDestlen);

extern s32 sdkBcdToAsc(s8 *pasDest, const u8 *pbcSrc, u32 siBcdSrcLen);

extern s32 sdkU16ToAsc(u16 const usSrc, u8 *pasDest);

extern s32 sdkU32ToHex(u8 *pheDest, u32 const uiSrc, u32 siHexlen);

extern s32 sdkU32ToAsc(u32 const uiSrc, u8 *pasDest);

extern s32 sdkU8ToAsc(u8 const ucSrc, u8 *pasDest);

extern s32 sdkAscToBcdR(u8 *pbcDest, const s8 *pasSrc, u32 siBcdlen);

extern s32 sdkBcdToU16(u16 *pusDest, const u8 *pbcSrc, u32 siSrclen);

extern s32 sdkU16ToBcd(u8 *pbcDest, u16 const usSrc, u32 uiDestlen);

extern s32 sdkXOR8(u8 *pheDest, const u8 *pheSrc1, const u8 *pheSrc2);

extern s32 sdkXOR16(u8 *pheDest, const u8 *pheSrc1, const u8 *pheSrc2);

extern s32 sdkEcb(u8 *pheDest, const u8 *pheSrc, u32 siLen);

extern u32 sdkMathValUint32(u8 *val);

extern s32 sdkMathsGetVersion(u8 *pasDest);

extern s32 sdkU32ToBcd(u8 *pbcDest, u32 const uiSrc, u32 siDestLen);

extern s32 sdkBcdToU8(u8 *pucDest, const u8 *pbcSrc, u32 siSrclen);

extern s32 sdkBcdToU32(u32 *puiDest, const u8 *pbcSrc, u32 siSrcLen);

extern s32 sdkHexToU16(u16 *pusDest, const u8 *pheSrc, u32 siHexLen);

extern s32 sdkHexToU32(u32 *puiDest, const u8 *pheSrc, u32 siHexLen);

extern s32 sdkU16ToHex(u8 *pheDest, u16 const usSrc, u32 siHexlen);

extern s32 sdkBcdToFloat(double *pDest, const u8 *pbcSrc, u32 siBcdSrcLen);

extern s32 sdkBcdCardNumToAsc(s8 *pasDest, const u8 *pbcSrc, u32 siBcdSrcLen);

extern void BcdAdd(u8 *Dest, u8 *Src, u32 Len);

extern bool sdkIsBcdNum(u8 const *pheSrc, s32 siSrclen);

extern s32 sdkBcdAdd(u8 *pbcDest, const u8 *pbcSrc1, u32 siBcdSrc1len, const u8 *pbcSrc2, u32 siBcdSrc2len);

extern void BcdSub(u8 *Dest, u8 *Src, u32 Len);

extern s32 sdkBcdSub(u8 *pbcDest, const u8 *pbcSrc1, u32 siBcdSrc1len, const u8 *pbcSrc2, u32 siBcdSrc2len);

extern s32 sdkCalcCUSUM(const u8 *pucSrc, u32 siNum);

extern s32 sdkCalcCrc16(const u8 *pucSrc, u32 siSrcLen);

extern u32 sdkCalcCrc32(u32 crc, u8 *szSrc, u32 dwSrcLen);

extern s32 sdkE90S(u8 *pheDest, const u8 *pheSrc, u32 siLen, const u8 *pheWk, SDK_ENCRYPT_MODE eMode);

extern s32 sdkE98S(u8 *pheDest, const u8 *phePin, const u8 *phePan, const u8 *pheWk, SDK_ENCRYPT_MODE eMode);

extern s32 sdkE99S(u8 *pheDest, const u8 *pheSrc, u32 siLen, const u8 *pheWk, SDK_ENCRYPT_MODE eMode);

extern s32 sdkE919S(u8 *pheDest, const u8 *pheSrc, u32 siLen, const u8 *pheWk, SDK_ENCRYPT_MODE eMode);

extern int sdkatoi(const char *str);

extern long sdkatol(const char *nptr);

extern s32 sdkHex2dec(char *hex);

extern U64 sdkAscToU64(const s8 *nptr);

extern U64 sdkHexStrToU64(char *s);

extern s32 sdkDesEncrypt(u8 *key, u32 keylen, u8 *data, u32 datalen);

extern s32 sdkDesDecrypt(u8 *key, u32 keylen, u8 *data, u32 datalen);

extern void sdkStrToLower(s8 *str);

extern int sdkisspace(char c);

extern int sdkisdigit(int c);

#define atoi(a)   sdkatoi( a )
#define isdigit(a)  sdkisdigit(a)
#define isspace(a) sdkisspace(a)

extern s8 *sdkStrdup(const s8 *s);

extern char *sdkStrtok(char *string_org, const char *demial);

extern int sdkStrSplit(const char *str, char *parts[], const char *delimiter);

extern void sdkStrReplace(char *data, char *rep, char *to);

extern s32 sdkSM2Decrypt(u8 *output, u32 *outputLen, u8 *input, u32 inputLen, u8 *sk, u32 skLen);

extern s32 sdkSM2Encrypt(u8 *output, u32 *outputLen, u8 *input, u32 inputLen, u8 *pk, u32 pkLen);

extern s32 sdkSM2Sign(u8 *sk, u8 *inputData, u32 inputDataLen, u8 *signOut);

extern bool sdkSM2VerifySign(u8 *pk, u32 pkLen, u8 *signData, u32 signDataLen, u8 *sm3Result, u32 sm3ResultLen);

extern s32 sdkSm3(u8 *pInput, u32 ilen, u8 *pOutput);

extern s32 sdkSm3WithPKAndId(u8 *msg, u32 msgLen, u8 *pk, u8 *hash);

extern s32 sdkSM2SignWithId(u8 *sk, u8 *pk, u8 *inputData, u32 inputDataLen, u8 *signOut);

extern s32 sdkSm4(u8 arithtype, u8 *pInput, u32 ilen, u8 *pOutput, u32 *pOutputLen, u8 *cKey);

#endif


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

